Opravneni procesu

Otázka od: Milan Tomes

8. 11. 2004 16:18

Zdravim vsechny,

mam takovy orisek - potrebuji zjistit zda ma proces opravneni pro
cteni/zapis do konkretni vetve registru (standardne HKEY_USERS\.Default, ale
i jinych napr. HKEY_LOCAL_MACHINE apod...) a take do konkretniho adresare na
disku (typicky Program files a dalsich...)...

Diky moc za odpovedi

S pozdravem

Milan Tomes


Odpovedá: Jiri Cincura

8. 11. 2004 20:04

Milan Tomes wrote:
> ale i jinych napr. HKEY_LOCAL_MACHINE apod...) a take do konkretniho
> adresare na disku (typicky Program files a dalsich...)...

Nevim, jak to zjistit, ale co to zkusit a kdyztak chytit exception? Je to
trochu pokulhavajici, ale pro zacatek to muze fungovat.

--
  Jiri Cincura
  e-mail: mailto:jiri@cincura.net; | http://www.cincura.net/
  mailto:xcincura@informatics.muni.cz | http://photo.cincura.net/
   ICQ: 314711544 | http://phorum.cincura.net/
 ---
  And if our times are difficult and perplexing,
  so are they challenging and filled with opportunity.
                                            -Robert F. Kennedy, 1961



Odpovedá: Milan Tomes

9. 11. 2004 7:26

Tohle reseni me samozrejme napadlo, ale nejak se mi do nej nechce... Rad
bych spise zjistil, zda existuje opravneni na zaklade pristupovych prav
uzivatele, pod kterym bezi dany proces bez pouziti metody try - except...

S pozdravem

Milan Tomes

> [mailto:delphi-l-owner@clexpert.cz]On Behalf Of Jiri Cincura
> Sent: Monday, November 08, 2004 8:04 PM
>
> Milan Tomes wrote:
> > ale i jinych napr. HKEY_LOCAL_MACHINE apod...) a take do konkretniho
> > adresare na disku (typicky Program files a dalsich...)...
>
> Nevim, jak to zjistit, ale co to zkusit a kdyztak chytit exception? Je to
> trochu pokulhavajici, ale pro zacatek to muze fungovat.


Odpovedá: Milan Tomes

9. 11. 2004 19:17

Trosku jsem na tom dneska pracoval a vysel mi zatim takovyto kod:

function DirCanWrite(ADir: string): boolean;
var
  pTrust: PTRUSTEEA;
  SD: Pointer;
  RV: DWORD;
  Access: Cardinal;
  DACL: PACL;

  HaveToken: boolean;
  Token: THandle;
  Count: DWORD;
  TokenInfo: PTokenUser;

  UserSid: PSid;

  User, Domain: string;
begin
  Result := false;
  UserSid := nil;
  if isWinNT then
  begin
    try
      HaveToken := false;
      try
        TokenInfo := nil;
        HaveToken := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
Token);
        if GetTokenInformation(Token, TokenUser, nil, 0, Count) or
          (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then
          RaiseLastOSError;
        TokenInfo := PTokenUser(AllocMem(Count));
        Win32Check(GetTokenInformation(Token, TokenUser, TokenInfo, Count,
Count));
        UserSid := AllocMem(GetLengthSid(TokenInfo^.User.Sid));
        CopySid(GetLengthSid(TokenInfo^.User.Sid), UserSid,
TokenInfo^.User.Sid);
      finally
        if TokenInfo <> nil then
          FreeMem(TokenInfo);
        if HaveToken then
          CloseHandle(Token);
      end;
      RV := GetNamedSecurityInfo(PChar(ADir), SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION, nil, nil, @DACL, nil, SD);
      try
        if RV <> ERROR_SUCCESS then
          raise
EG3CoreError.CreateFmt('Nastala chyba poi zjis?ovani
poistupovych prav k objektu '
+ ADir + ' (GetNamedSecurityInfo, kod chyby:
%d) !!!', [RV])
        else
        begin
          if DACL = nil then
//NULL DACL - neni povoleno
            raise
EG3OSError.Create('Nastala chyba poi zjis?ovani
poistupovych prav k objektu '
+ ADir + ' (GetNamedSecurityInfo - Dacl = nil)
!!!');
          pTrust := AllocMem(SizeOf(_TRUSTEE_A));
          try
            BuildTrusteeWithNameA(pTrust, UserSid);
// pTrust^.pMultipleTrustee := nil;
// pTrust^.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
// pTrust^.TrusteeForm := TRUSTEE_IS_SID;
// pTrust^.TrusteeType := TRUSTEE_IS_USER;
// pTrust^.ptstrName := UserSid;

// if IsValidSid(pTrust^.ptstrName) then
// LookupAccountBySid(pTrust^.ptstrName, User, Domain)
// else
// User := pTrust^.ptstrName;

            RV := GetEffectiveRightsFromAclA(DACL^, pTrust^, Access);
            if RV <> ERROR_SUCCESS then
              raise
EG3CoreError.CreateFmt('Nastala chyba poi zjis?ovani
poistupovych prav k objektu '
+ ADir + ' (GetEffectiveRightsFromAcl, kod
chyby: %d) !!!', [RV]);
            Result := (Access and GENERIC_WRITE) = GENERIC_WRITE;
          finally
            FreeMem(pTrust);
          end;
        end;
      finally
        if SD <> nil then
          LocalFree(Cardinal(SD));
      end;
    finally
      if UserSid <> nil then
        FreeMem(UserSid);
    end;
  end
  else
    Result := true;
end;

Tato konstrustrukce funguje az na jednu malickost - pri volani
FreeMem(pTrust) to spadne na Invalid pointer operation.

Pokud misto volani BuildTrusteeWithNameA pouziju prime prirazeni do
struktury pTrust, tak se vyjimka nevyvola, ale kod nefunguje resp. volani
GetEffectiveRightsFromAclA skonci chybou 1337 - Security ID is invalid. SID
je ale spravne - mozno overit volanim IsValidSid.
Pokud upravim datovy typ promenne pTrust na _TRUSTEE_A, zrusim dereference a
u volani BuildTrusteeWithNameA naopak referuji (@pTrust), tak se mi
pravdepodobne prepisuje pamet, protoze pred volanim teto funkce je UserSid
spravne a po navratu je nil.

Absolutne nevim co s tim - pokud ma nekdo tuseni co s tim, tak mu budu
opravdu zauzlovan.

Cil tehle funkce je vraceni boolean hodnoty, zda je do specifikovaneho
adresare mozno cokoliv zapsat - uzivatelska prava. Vim, ze to mohu udelat
ofenzivni metodou, ale ja radsi otestuji, jestli to prava umoznuji a teprve
potom budu neco delat.

S pozdravem

Milan Tomes



Odpovedá: Jakub Cermak

9. 11. 2004 20:09

Zkus misto pTrust := AllocMem(SizeOf(_TRUSTEE_A));
 dat GetMem (vetsinou mi FreeMem selhalo pokud se pamet nealokovala pres
Getmem, hlasilo to invalid pointer operation). Ale je to bez zaruky

Jakub Cermak
ja.cermi@centrum.cz


Odpovedá: Milan Tomes

9. 11. 2004 20:54

Ani GetMem neprojde spravne. Zkousel jsem New - Dispose, GetMem/AllocMem -
FreeMem a nic. Problem nastane teprve v okamziku, kdy ten ukazatel predam
funkci BuildTrusteeWithName. Kdyz toto volani zrusim, tak je vse - vcetne
dealokace v poradku...

S pozdravem

Milan Tomes

> [mailto:delphi-l-owner@clexpert.cz]On Behalf Of Jakub Cermak
> Sent: Tuesday, November 09, 2004 8:09 PM
>
> Zkus misto pTrust := AllocMem(SizeOf(_TRUSTEE_A));
> dat GetMem (vetsinou mi FreeMem selhalo pokud se pamet nealokovala pres
> Getmem, hlasilo to invalid pointer operation). Ale je to bez zaruky